package com.shoothzj.example.storage.hibernate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.query.NativeQuery;

import java.io.Serializable;
import java.util.List;

public class HibernateService {
    protected final SessionFactory sessionFactory;

    public HibernateService(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    public List<?> query(String query) {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        List<?> resultList = session.createQuery(query).getResultList();
        transaction.commit();
        session.close();
        return resultList;
    }

    public <T> List<T> query(String query, Class<T> tClass) {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        List<T> resultList = session.createQuery(query, tClass).getResultList();
        transaction.commit();
        session.close();
        return resultList;
    }

    public Object queryUniqueResult(String query) {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Object result = session.createQuery(query).uniqueResult();
        transaction.commit();
        session.close();
        return result;
    }

    public int update(String query) {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        int result = session.createQuery(query).executeUpdate();
        transaction.commit();
        session.close();
        return result;
    }

    public Serializable save(Object object) {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Serializable result = session.save(object);
        transaction.commit();
        session.close();
        return result;
    }

    public <T> T get(Serializable id, Class<T> tClass) {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        T result = session.get(tClass, id);
        transaction.commit();
        session.close();
        return result;
    }

    public List<?> nativeQuery(String sql) {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        NativeQuery<?> nativeQuery = session.createNativeQuery(sql);
        List<?> resultList = nativeQuery.getResultList();
        transaction.commit();
        session.close();
        return resultList;
    }

    public int nativeUpdate(String sql) {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        NativeQuery<?> nativeQuery = session.createNativeQuery(sql);
        int result = nativeQuery.executeUpdate();
        transaction.commit();
        session.close();
        return result;
    }
}
